#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <time.h>
#include <dos.h>
#include "konsole.h"

#define SCREEN_BACKGROUND_COLOUR 128
#define RED_TEXT 132
#define YELLOW_TEXT 142
#define GREEN_TEXT 138
#define BRIGHT_WHITE_TEXT 143
#define DULL_WHITE_TEXT 135
#define NORMAL_TEXT 128

#define T_PASSWORD 1
#define T_CURRENCY 2
#define T_REAL_NUMERIC 3
#define T_INTEGER_NUMBERIC 4
#define T_FREE_TEXT 5
#define T_DATE 6
#define T_STRICT_NUMERIC 7
#define T_TELEPHONE 8


#define EMPLOYEE_SECURITY_CODE "pass123"
#define APPLICATION_START 0
#define MAX_EMPLOYEE_LOGIN_FAILED_ATTEMPT 3

#define ACCOUNT_MINIMUM_BALANCE 200.00
#define BILL_PAYMENT_CHARGE 20.00
#define REGULAR_TRANSACTION_CHARGE 10.00

/*GCT*/
#define CREDIT_GCT 25.0

/*Bonus Credit Amount %*/
#define DIGICEL_BONUS 15
#define CLARO_BONUS 12
#define LIME_BONUS 5

/*Purchase amounts*/
#define AMOUNT_1 200
#define AMOUNT_2 300
#define AMOUNT_3 500
#define AMOUNT_4 1000

/*Transaction type*/
#define BILL_PAYMENT 0
#define PURCHASE_CREDIT 1
#define DEPOSIT 2
#define WITHDRAWAL 3
#define TRANSFER_FUNDS 4

/*file paths*/
#define ACCOUNT_FILE_PATH "account.dat"
#define TRANSACTION_FILE_PATH "transaction.dat"

/*Menu Codes*/
#define FILE_SETUP_MENU 0
#define SELECT_USER_MENU 1
#define EMPLOYEE_LOGIN_MENU 2
#define EMPLOYEE_MAIN_MENU 3
#define OPEN_NEW_ACCOUNT_MENU 4
#define CLOSE_ACCOUNT_MENU 5
#define CUSTOMER_LOGIN_MENU 6
#define TRANSFER_FUNDS_MENU 8
#define DEPOSIT_MENU 9
#define CHECK_BALANCE_MENU 10
#define PAY_BILLS_MENU 11
#define PURCHASE_CREDIT_MENU 12
#define CUSTOMER_MAIN_MENU 13
#define WITHDRAWAL_MENU 14
#define OPENED_ACCOUNTS_MENU 15
#define DORMANT_ACCOUNTS_MENU 16
#define FEES_EARNED_MENU 17
#define REPORTS_MENU 18
#define UPDATE_ACCOUNT_MENU 19
#define BANK_STATEMENT_MENU 20

#define EXIT_MENU 100

typedef struct Customer
{
    char firstName[32];
    char lastName[40];
    char dob[10];
}customer;

typedef struct Account
{
    int accNumber; //Customer's Account Number
    customer customerObj; //Customer's Information
    double balance; //Account Balance
    int status; //Account status (i.e. closed, open)
    char pin[5]; //Account Personal Indentification Number
    time_t openedDate; //Date and time the account opened
    time_t closedDate; //Date and time the account was closed
}account;

typedef struct Transaction
{
    int accNumber; //Customer's Account Number
    int type; /*Type of transaction (i.e Withdrawal, Deposit, Transfer Funds,...)*/
    char comments[30]; //Comments
    time_t date; /*Date and time the transaction was conducted*/
    double ammount; /*The cost of the transaction without the bank charge*/
    double charge; /*Bank charge of the transaction*/
    double balance; /*Customer's Account balance after total cost of the transaction*/
}transaction;


/*employee menu functions*/
bool employeeLoginController(void);
void showEmplyeeMainMenu(void);
int employeeMainMenuController();
int openNewAccount(void);
int closeAccount(void);

/*reports menu functions*/
int reportsMenuController(void);
int openedClosedAccountsReport(void);
int feesEarnedReport(void);
int dormantAccount(void);

/*customer menu functions*/
void showCustomerMainMenu(void);
bool customerLoginController(account *);
int customerMainMenuController(account *);
int bankStatement(account *);
int purchaseCreditMenu(account *);
int withdrawalMenu(account *);
int depositMenu(account *);
int checkBalanceMenu(account *);
int transerFundsMenu(account *);
int payBillsMenu(account *);

/*account filing functions*/
int updateAccountInFile(account*);
int getAccountFromFile(account*);
int getAnyAccountFromFile(account*);
int saveNewAccount(account*);

/*account transaction filing function*/
int saveTransactionToFile(transaction *);
int isAmountTransaction(int,int);
int isAccountDormant(account);

/*miscellaneous functions*/
int exitMenu(void);
void displayAccountBalance(double);
void singleFrame(int,int,int,int,char[]);
void underline(int,int,int);
void initScreen(void);
char* stringInput(int,int,int);
char* getServiceProvider (char);
float bonusCredit(char,float);
void prompt(void);
char getChar(void);

const char months [12][9] = {"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"};
const char transactionTypes [5][20] ={"Bill Payement","Credit Purchase", "Deposit", "Withdrawal","Transfer Funds"};
const char accountStatus [2][8] = {"Closed","Open"};

int main()
{
    //set the title of the console
    setConsoleTitle("Royal Bank Of Stratland");

    /*set the console's height and width; and centers the console*/
    centerConsole(680,600);

    //set the console virtical buffer size
    setBufferHeigth(47);


    //define the program's starting menu
    int entryPoint = APPLICATION_START;

    //declare a variable of type account
    account accountObj;
    /*declare a pointer of type account and set it to point to accounObj*/
    account *accountPtr = &accountObj;

    do
    {
        //call master module to launch a menu
       entryPoint = masterMenuController(masterMenuController(entryPoint,accountPtr),accountPtr);
    }while(true);

    return 0;
}

void initScreen(void)
{
    clearScreen();
    setScreenColour(SCREEN_BACKGROUND_COLOUR);
    setTextColour(NORMAL_TEXT);
    setCursor(false,1);
    singleFrame(0,79,0,45,"normal");
}

int initFiles()
{
    int startPos = 12;
    int startCount = 0;
    int status =0;
    FILE *filePtr;

    //open a read only binary stream to file
    filePtr = fopen(ACCOUNT_FILE_PATH,"rb");

    //if file did not open
    if(filePtr==NULL)
    {
        moveCursor(15,10);
        printf("Creating file(s):");
        Sleep(800);
        /*file does not exist. Hence, create it by opening a write only binary stream to file*/
        filePtr = fopen(ACCOUNT_FILE_PATH,"wb");
        // if file write/creation failed
        if(filePtr==NULL)
        {
            moveCursor(32,startPos);
            setTextColour(RED_TEXT);
            printf("%d. Error creating file 'account.dat'.",++startCount);
            setTextColour(NORMAL_TEXT);
            status=-1;
        }
        else // if file exist/created
        {
            moveCursor(32,startPos);
            setTextColour(GREEN_TEXT);
            printf("%d. File 'account.dat' created.",++startCount);
            setTextColour(NORMAL_TEXT);
            status=1;
            fclose(filePtr);
        }
    }
    else //if file is opened
    {
        fclose(filePtr);
    }
    return status;
}

int fileSetupMenuController(void)
{
    int result;
    initScreen();

    result = initFiles();

    if(result == 0)
    {
        return SELECT_USER_MENU;
    }
    else if(result>0)
    {
        Sleep(1000);
        moveCursor(25,30);
        printf("PRESS ANY KEY TO CONTINUE");
        prompt();
        return SELECT_USER_MENU;
    }
    else
    {
        Sleep(1000);

        moveCursor(10,20);
        setTextColour(YELLOW_TEXT);
        printf("WARNING: Error(s) were encountered while creating the file(s)");

        moveCursor(20,21);
        printf("Some features of the program might not properly function.");
        setTextColour(NORMAL_TEXT);

        moveCursor(20,25);
        printf("Do you want to continue?");

        moveCursor(30,28);
        printf("[1] YES        [2] NO");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    return SELECT_USER_MENU;
                break;
                case '2':
                    return EXIT_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    return 0;
}


int masterMenuController(int code, account *accountPtr)
{
    switch(code)
    {
        case FILE_SETUP_MENU:
            return fileSetupMenuController();
        break;
        case SELECT_USER_MENU:
            return selectUserMenuController();
        break;
        case EMPLOYEE_LOGIN_MENU:
            if(employeeLoginController())
            {
                return EMPLOYEE_MAIN_MENU;
            }
        break;
        case EMPLOYEE_MAIN_MENU:
            return employeeMainMenuController();
        break;
        case OPEN_NEW_ACCOUNT_MENU:
            return openNewAccount();
        break;

        case CLOSE_ACCOUNT_MENU:
            return closeAccount();
        break;

        case CUSTOMER_LOGIN_MENU:
            if(customerLoginController(accountPtr))
            {
                return CUSTOMER_MAIN_MENU;
            }
        break;

        case CUSTOMER_MAIN_MENU:
            return customerMainMenuController(accountPtr);
        break;

        case TRANSFER_FUNDS_MENU:
            return transerFundsMenu(accountPtr);
        break;

        case DEPOSIT_MENU:
            return depositMenu(accountPtr);
        break;

        case CHECK_BALANCE_MENU:
            return checkBalanceMenu(accountPtr);
        break;

        case PAY_BILLS_MENU:
            return payBillsMenu(accountPtr);
        break;

        case PURCHASE_CREDIT_MENU:
            return purchaseCreditMenu(accountPtr);
        break;

        case WITHDRAWAL_MENU:
            return withdrawalMenu(accountPtr);
        break;

        case REPORTS_MENU:
            return reportsMenuController();
        break;

        case OPENED_ACCOUNTS_MENU:
            return openedClosedAccountsReport();
        break;

        case DORMANT_ACCOUNTS_MENU:
            return dormantAccount();
        break;

        case FEES_EARNED_MENU:
            return feesEarnedReport();
        break;

        case UPDATE_ACCOUNT_MENU:
            return updateAccount();
        break;

        case BANK_STATEMENT_MENU:
            return bankStatement(accountPtr);
        break;

        case EXIT_MENU:
            return exitMenu();
        break;

        default:
        break;
    }
}

void showSelectUserMenu(void)
{
    initScreen();
    moveCursor(18,18);
    printf("[1] Employee Utility          [2] Customer");
    moveCursor(2,44);
    printf("[0] Exit");
}

int selectUserMenuController(void)
{
    showSelectUserMenu();
    do
    {
        char option =   getChar();
        switch(option)
        {
            case '0':
                return EXIT_MENU;
            break;
            case '1':
                return EMPLOYEE_LOGIN_MENU;
            break;
            case '2':
                return CUSTOMER_LOGIN_MENU;
            break;
            default:
            break;
        }
    }while(true);
    return 0;
}

int exitMenu(void)
{
    exit(0);
    return EXIT_MENU;
}

void showEmployeeLogin(void)
{
    initScreen();
    moveCursor(25,18);
    printf("Enter Secuity code: ");
}

bool employeeLoginController(void)
{
    char *securityCode;
    int failedAttempt = 0;

    showEmployeeLogin();

    do
    {
        setCursor(true,1);
        moveCursor(45,18);

        securityCode = stringInput(T_PASSWORD,8,32);

        if(strcmp(EMPLOYEE_SECURITY_CODE,securityCode)==0)
        {
            break;
        }
        else
        {
            if(failedAttempt<MAX_EMPLOYEE_LOGIN_FAILED_ATTEMPT)
            {
                failedAttempt++;
                showEmployeeLogin();

                moveCursor(20,14);
                setTextColour(RED_TEXT);
                printf("Attempt %d of %d failed.",failedAttempt,MAX_EMPLOYEE_LOGIN_FAILED_ATTEMPT);
                setTextColour(NORMAL_TEXT);
            }
            else
            {
                initScreen();
                moveCursor(20,30);

                setTextColour(RED_TEXT);
                printf("System Locked!");
                setTextColour(NORMAL_TEXT);

                while(true)
                {
                    prompt();
                }
            }
        }
    }while(true);
    return true;
}


void showEmplyeeMainMenu(void)
{
    initScreen();

    moveCursor(28,8);
    printf("Employee Ultilty Main Menu");
    underline(27,9,28);

    moveCursor(8,18);
    printf("[1] Open New Account    [2] Update Account     [3] Close Account");
    moveCursor(8,21);
    printf("[4] Reports");
    moveCursor(2,44);
    printf("[0] Logout                                                         [9] Exit");
}

int employeeMainMenuController(void)
{
    showEmplyeeMainMenu();
    do
    {
        switch(getChar())
        {
            case '0':
                return SELECT_USER_MENU;
            break;
            case '1':
                return OPEN_NEW_ACCOUNT_MENU;
            break;
            case '2':
                return UPDATE_ACCOUNT_MENU;
            break;
            case '3':
                return CLOSE_ACCOUNT_MENU;
            break;
            case '4':
                return REPORTS_MENU;
            break;

            default:
            break;
        }
    }while(true);
    return 0;
}


void showCustomerLogin(void)
{
    initScreen();

    moveCursor(25,16);
    printf("Enter your Account #: ");
    moveCursor(25,18);
    printf("Enter your PIN: ");
}

bool customerLoginController(account *accountObjPtr)
{
    char accountNumber[12];
    char securityCode[5];
    int getAccountResult;
    int failedAttempt = 0;

    showCustomerLogin();

    do
    {
        setCursor(true,1);

        moveCursor(47,16);
        strcpy(accountNumber,stringInput(T_STRICT_NUMERIC,1,12));

        moveCursor(41,18);
        strcpy(securityCode,stringInput(T_PASSWORD,1,5));

        accountObjPtr->accNumber = atoi(accountNumber);

        //printf("\nFirst Name: %s\nLast Name: %s\nDOB: %s\nOpening Amount: %f\nPIN: %s\n acc#: %d",accountObjPtr->customerObj.fisrtName,accountObjPtr->customerObj.lastName,accountObjPtr->customerObj.dob,accountObjPtr->balance,accountObjPtr->pin,accountObjPtr->accNumber);
        getAccountResult = getAccountFromFile(accountObjPtr);



        if(getAccountResult==1 || getAccountResult==0)
        {
            if(getAccountResult==1 && strcmp(accountObjPtr->pin,securityCode)==0 && accountObjPtr->status == 1)
            {
                break;
            }
            else
            {
                failedAttempt++;
                if(failedAttempt<MAX_EMPLOYEE_LOGIN_FAILED_ATTEMPT)
                {
                    showCustomerLogin();

                    moveCursor(20,10);
                    setTextColour(RED_TEXT);
                    printf("Attempt %d of %d failed.",failedAttempt,MAX_EMPLOYEE_LOGIN_FAILED_ATTEMPT);
                    setTextColour(NORMAL_TEXT);
                }
                else
                {
                    initScreen();

                    moveCursor(20,30);
                    setTextColour(RED_TEXT);
                    printf("System Locked!");
                    setTextColour(NORMAL_TEXT);

                    while(true)
                    {
                        prompt();
                    }
                }
            }
        }
    }while(true);
    return true;
}

void showCustomerMainMenu(void)
{
    initScreen();

    moveCursor(30,7);
    printf("Customer Main Menu");
    underline(29,8,20);

    moveCursor(8,15);
    printf("[1] Transfer Funds        [2] Deposit       [3] Check Balance");
    moveCursor(3,19);
    printf("[4] Pay Bills   [5] Purchase Credit    [6] Withdrawal   [7] Bank Statement");
    moveCursor(3,44);
    printf("[0] Logout                                                         [9] Exit");
}

int customerMainMenuController(account *accountObjPtr)
{
    showCustomerMainMenu();

    if(isAccountDormant(*accountObjPtr)==1)
    {
        moveCursor(3,4);
        printf("Status: ");
        setTextColour(YELLOW_TEXT);
        printf("Your account is DORMANT.");
        setTextColour(NORMAL_TEXT);
    }

    displayAccountBalance(accountObjPtr->balance);
    do
    {
        switch(  getChar())
        {
            case '0':
                return CUSTOMER_LOGIN_MENU;
            break;
            case '1':
                return TRANSFER_FUNDS_MENU;
            break;
            case '2':
                return DEPOSIT_MENU;
            break;
            case '3':
                return CHECK_BALANCE_MENU;
            break;
            case '4':
                return PAY_BILLS_MENU;
            break;
            case '5':
                return PURCHASE_CREDIT_MENU;
            break;
            case '6':
                return WITHDRAWAL_MENU;
            break;
            case '7':
                return BANK_STATEMENT_MENU;
            break;
            case '9':
                return EXIT_MENU;
            default:
            break;
        }
    }while(true);
    return 0;
}

void displayAccountBalance(double balance)
{
    moveCursor(60,4);
    printf("Balance: $%.2f",balance);
}

int transerFundsMenu(account *accountObjPtr)
{
    transaction transactionObj;
    account toAccountObj;
    int getAccountStatus;
    char accNumber[6];
    char amountStr[13];
    double amountDec;
    double fee;
    int freeTrans = 0;

    initScreen();

    setCursor(true,1);

    moveCursor(32,4);
    printf("Transfer Funds");
    underline(31,5,16);

    //get the number of free transactions remaining for the month
    freeTrans = isAmountTransaction(accountObjPtr->accNumber,5);

    if(freeTrans==0)
    {
        //charge regular
        fee = REGULAR_TRANSACTION_CHARGE;
    }
    else
    {
        moveCursor(6,9);
        printf("%d free tranasactions remaining for this month",freeTrans);
    }
    moveCursor(6,8);
    printf("Transaction Fee: $%.2f",fee);

    moveCursor(15,13);
    printf("Destination Account#:");

    moveCursor(15,15);
    printf("Transfer Amount: $");

    moveCursor(37,13);
    /*get text input from the user and copy it to accountObj->customerObj.fisrtName*/
    strcpy(accNumber,stringInput(T_STRICT_NUMERIC,1,5));

    moveCursor(33,15);
    /*get text input from the user and copy it to accountObj->customerObj.lastName*/
    strcpy(amountStr,stringInput(T_CURRENCY,1,12));

    toAccountObj.accNumber = atoi(accNumber);
    amountDec = atof(amountStr);

    if(toAccountObj.accNumber==accountObjPtr->accNumber)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: You cannot transfer funds to your current account.");
        setTextColour(NORMAL_TEXT);
    }
    else if(accountObjPtr->balance - amountDec + fee < ACCOUNT_MINIMUM_BALANCE)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: This transfer will put your balance below $%.2f",ACCOUNT_MINIMUM_BALANCE);
        setTextColour(NORMAL_TEXT);
    }
    else
    {
        getAccountStatus = getAccountFromFile(&toAccountObj);


        moveCursor(17,27);
        printf("Do you really want to transfer %.2f to %d?",amountDec,toAccountObj.accNumber);

        moveCursor(30,31);
        printf("[1] YES        [2] NO");
        moveCursor(62,44);
        printf("[0] Logout                                                         [9] Exit");
        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '0':
                    return CUSTOMER_LOGIN_MENU;
                break;
                case '1':
                    initScreen();
                    if(getAccountStatus==1)
                    {
                        accountObjPtr->balance -= amountDec + fee;
                        toAccountObj.balance += amountDec;

                        //if the sender and receiver accounts are updated successfully
                        if(updateAccountInFile(&toAccountObj)==1 && updateAccountInFile(accountObjPtr)==1)
                        {
                            //record the transaction info
                            transactionObj.accNumber=accountObjPtr->accNumber;
                            transactionObj.ammount=amountDec;
                            transactionObj.charge = fee; // set correct charge
                            transactionObj.type = TRANSFER_FUNDS;
                            transactionObj.balance = accountObjPtr->balance;
                            transactionObj.date = time(NULL);
                            strcpy(transactionObj.comments ,"misc");

                            moveCursor(8,20);
                            setTextColour(GREEN_TEXT);
                            printf("Success: %.2f was transferred to %d. Your account balance is $%.2f",amountDec,toAccountObj.accNumber,accountObjPtr->balance);
                            setTextColour(NORMAL_TEXT);

                            //if transaction was saved to the file
                            if(saveTransactionToFile(&transactionObj)==1)
                            {
                                //printf("saved to tranaction log");
                            }
                        }
                        else
                        {
                            moveCursor(18,20);
                            setTextColour(RED_TEXT);
                            printf("Failure: An error occurred. Transfer aborted");
                            setTextColour(NORMAL_TEXT);
                        }
                    }
                    else
                    {
                        moveCursor(18,20);
                        setTextColour(BRIGHT_WHITE_TEXT);
                        printf("Account %d does not exist",toAccountObj.accNumber);
                        setTextColour(NORMAL_TEXT);
                    }

                    moveCursor(25,27);
                    printf("PRESS ANY KEY TO CONTINUE");

                    prompt();
                    return CUSTOMER_MAIN_MENU;
                break;
                case '2':
                    return CUSTOMER_MAIN_MENU;
                break;
                case '9':
                    return CUSTOMER_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}


int withdrawalMenu(account *accountObjPtr)
{
    char amountStr[13];
    double amountDec = 0;
    double fee = 0;
    int freeTrans = 0;
    transaction transactionObj;

    initScreen();

    setCursor(true,1);

    moveCursor(32,4);
    printf("Withdraw Funds");
    underline(31,5,15);

    //get the number of free transactions remaining for the month
    freeTrans = isAmountTransaction(accountObjPtr->accNumber,5);

    if(freeTrans==0)
    {
        fee = REGULAR_TRANSACTION_CHARGE;
    }
    else
    {
        moveCursor(6,9);
        printf("%d free tranasactions remaining for this month",freeTrans);
    }

    moveCursor(6,8);
    printf("Transaction Fee: $%.2f",fee);

    moveCursor(15,13);
    printf("Withdrawal Amount: $");

    moveCursor(35,13);
    /*get text input from the user and copy it to accountObj->customerObj.lastName*/
    strcpy(amountStr,stringInput(T_CURRENCY,1,12));

    //convert the string to a float
    amountDec = atof(amountStr);

    if(accountObjPtr->balance - amountDec + fee < ACCOUNT_MINIMUM_BALANCE)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: This withdrawal will put your balance below $%.2f",ACCOUNT_MINIMUM_BALANCE);
        setTextColour(NORMAL_TEXT);
    }
    else
    {
        moveCursor(17,27);
        printf("Do you really want to withdraw $%.2f?",amountDec);

        moveCursor(30,31);
        printf("[1] Yes       [2] No");
        moveCursor(62,44);
        printf("[0] Logout                                                         [9] Exit");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '0':
                    return CUSTOMER_LOGIN_MENU;
                break;
                case '1':
                    initScreen();
                    accountObjPtr->balance -= amountDec + fee;

                     //if the account is updated successfully
                    if(updateAccountInFile(accountObjPtr)==1)
                    {
                        //record transaction data
                        transactionObj.accNumber = accountObjPtr->accNumber;
                        transactionObj.ammount = amountDec;
                        transactionObj.charge = fee;
                        transactionObj.type = WITHDRAWAL;
                        transactionObj.balance = accountObjPtr->balance;
                        transactionObj.date = time(NULL);
                        strcpy(transactionObj.comments ,"misc");

                        moveCursor(9,20);
                        setTextColour(GREEN_TEXT);
                        printf("Success: $%.2f was withdrawn. Your account balance is $%.2f",amountDec,accountObjPtr->balance);
                        setTextColour(NORMAL_TEXT);

                        if(saveTransactionToFile(&transactionObj)==1)
                        {
                            //printf("saved to tranaction log");
                        }
                    }
                    else /*if account was not updated successfully*/
                    {
                        accountObjPtr->balance += amountDec + fee;
                        moveCursor(17,20);
                        setTextColour(RED_TEXT);
                        printf("Failure: An error occurred. Withdrawal aborted");
                        setTextColour(NORMAL_TEXT);
                    }

                    moveCursor(25,27);
                    printf("PRESS ANY KEY TO CONTINUE");

                    prompt();
                    return CUSTOMER_MAIN_MENU;
                break;
                case '2':
                    return CUSTOMER_MAIN_MENU;
                break;
                case '9':
                    return EXIT_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}

int purchaseCreditMenu(account *accountObjPtr)
{
    char phoneNum[9];
    double amountDec = 0;
    double creditAmount = 0;
    double taxAmount = 0;
    double fee = 0;
    int flag = 0;
    int freeTrans =0;
    transaction transactionObj;

    do
    {
        initScreen();
        setCursor(true,1);

        moveCursor(32,4);
        printf("Purchase Credit");
        underline(31,5,16);

        //get the number of free transactions remaining for the month
        freeTrans = isAmountTransaction(accountObjPtr->accNumber,5);

        if(freeTrans==0)
        {
            fee = REGULAR_TRANSACTION_CHARGE;
        }
        else
        {
            moveCursor(6,9);
            printf("%d free tranasactions remaining for this month",freeTrans);
        }

        moveCursor(6,8);
        printf("Transaction Fee: $%.2f",fee);

        moveCursor(14,13);
        printf("Phone Number:");

        moveCursor(28,13);
        /*get text input from the user and copy it to accountObj->customerObj.lastName*/
        strcpy(phoneNum,stringInput(T_TELEPHONE,1,8));

        /*if the phone number eneter is: not 8 characters long, start with 1,start with 0*/
        if(strlen(phoneNum)!=8 || phoneNum[0]=='1' || phoneNum[0]=='0')
        {
            if(phoneNum[0]=='1')
            {
                moveCursor(14,8);
                setTextColour(RED_TEXT);
                printf("Invalid Number: No phone number begins with a 1.");
                setTextColour(NORMAL_TEXT);
            }
            if(phoneNum[0]=='0')
            {
                moveCursor(14,8);
                setTextColour(RED_TEXT);
                printf("Invalid Number: No phone number begins with a 0.");
                setTextColour(NORMAL_TEXT);
            }
            if(strlen(phoneNum)!=8)
            {
                moveCursor(14,10);
                setTextColour(RED_TEXT);
                printf("Invalid Number: Number must be 7 numeric characters.");
                setTextColour(NORMAL_TEXT);
            }

            moveCursor(14,20);
            printf("Do you want to try again?");

            if(confirmationPrompt(30,22)==1)
            {

            }
            else
            {
                return CUSTOMER_MAIN_MENU;
            }
        }
        else /*if phone number is valid*/
        {
            do
            {
                initScreen();
                moveCursor(8,7);
                printf("Credit Purchase Fee: $%.2f",REGULAR_TRANSACTION_CHARGE);
                moveCursor(8,10);
                printf("The Service Provider of %s is %s.",phoneNum,getServiceProvider(phoneNum[0]));

                moveCursor(12,16);
                printf("[1] $200       [2] $300       [3] $500       [4] $1000");
                moveCursor(12,19);
                printf("[5] Cancel");
                moveCursor(2,44);
                printf("[9] Main Menu                                                    [0] Logout");
                do
                {
                    switch( getChar())
                    {
                        case '1':
                            creditAmount = AMOUNT_1;
                            flag=1;
                        break;
                        case '2':
                            creditAmount = AMOUNT_2;
                            flag=1;
                        break;
                        case '3':
                            creditAmount = AMOUNT_3;
                            flag=1;
                        break;
                        case '4':
                            creditAmount = AMOUNT_4;

                            flag=1;
                        break;
                        case '5':
                            return CUSTOMER_MAIN_MENU;
                        break;

                        case '9':
                            return CUSTOMER_MAIN_MENU;
                        break;

                        case '0':
                            return SELECT_USER_MENU;
                        break;
                    }
                }while(flag==0);

                flag=0;
                amountDec += creditAmount;
                taxAmount = CREDIT_GCT * 0.01 * creditAmount;
                amountDec += taxAmount + REGULAR_TRANSACTION_CHARGE;

                if(accountObjPtr->balance - amountDec + fee< ACCOUNT_MINIMUM_BALANCE)
                {
                    moveCursor(6,23);
                    setTextColour(RED_TEXT);
                    printf("Denied: This credit purchase will put your balance below $%.2f",ACCOUNT_MINIMUM_BALANCE);
                    setTextColour(NORMAL_TEXT);

                    moveCursor(14,26);
                    printf("Do you want to try another amount?");

                    if(confirmationPrompt(30,28)==1)
                    {
                        amountDec = 0;
                        taxAmount = 0;
                        continue;
                    }
                    else
                    {
                        return CUSTOMER_MAIN_MENU;
                    }
                }
                else
                {

                    moveCursor(14,25);
                    printf("You are about to purchase $%.2f from %s.",creditAmount,getServiceProvider(phoneNum[0]));

                    moveCursor(14,27);
                    printf("Total Amount of this transaction: $%.2f",amountDec);

                    moveCursor(14,33);
                    printf("Do you really want to purchase this credit?");

                    moveCursor(30,35);
                    printf("[1] Yes        [2] No");

                    do
                    {
                        //get a single key input from user
                        switch(  getChar())
                        {
                            case '1':
                                initScreen();
                                accountObjPtr->balance -= amountDec + fee;

                                /*if account is updated successfully*/
                                if(updateAccountInFile(accountObjPtr)==1)
                                {

                                    transactionObj.accNumber=accountObjPtr->accNumber;
                                    transactionObj.ammount=amountDec;
                                    transactionObj.charge = fee;
                                    transactionObj.type = PURCHASE_CREDIT;
                                    transactionObj.balance = accountObjPtr->balance;
                                    transactionObj.date = time(NULL);
                                    strcpy(transactionObj.comments ,"misc");

                                    moveCursor(9,15);
                                    setTextColour(GREEN_TEXT);
                                    printf("Success: $%.2f credit purchased. Your account balance is $%.2f",creditAmount,accountObjPtr->balance);
                                    setTextColour(NORMAL_TEXT);

                                    moveCursor(9,18);
                                    printf("You have received $%.2f bonus credit.",bonusCredit(phoneNum[1],creditAmount));

                                    moveCursor(9,20);
                                    printf("Total credit received is $%.2f",bonusCredit(phoneNum[1],creditAmount)+creditAmount);

                                    if(saveTransactionToFile(&transactionObj)==1)
                                    {
                                        //printf("saved to tranaction log");
                                    }
                                }
                                else /*if account was NOT updated successfully*/
                                {
                                    accountObjPtr->balance += amountDec + fee;

                                    moveCursor(10,20);
                                    setTextColour(RED_TEXT);
                                    printf("Failure: An error occurred. Credit purchase aborted");
                                    setTextColour(NORMAL_TEXT);
                                }

                                moveCursor(25,27);
                                printf("PRESS ANY KEY TO CONTINUE");

                                prompt();
                                return CUSTOMER_MAIN_MENU;
                            break;
                            case '2':
                                return CUSTOMER_MAIN_MENU;
                            break;
                            default:
                            break;
                        }
                    }while(true);
                }
            }while(true);
        }
    }while(true);

    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}


int checkBalanceMenu(account *accountObjPtr)
{
    initScreen();

    moveCursor(32,4);
    printf("Check Balance");
    underline(31,5,14);

    moveCursor(17,13);
    printf("%s, your current account balance is $%.2f",accountObjPtr->customerObj.firstName,accountObjPtr->balance);

    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}

int depositMenu(account *accountObjPtr)
{
    char amountStr[13];
    int amountDec = 0;
    double fee = 0;
    int freeTrans;
    transaction transactionObj;

    initScreen();

    setCursor(true,1);

    moveCursor(32,4);
    printf("Deposit Funds");
    underline(31,5,14);


    //get the number of free transactions remaining for the month
    freeTrans = isAmountTransaction(accountObjPtr->accNumber,5);

    if(freeTrans==0)
    {
        fee = REGULAR_TRANSACTION_CHARGE;
    }
    else
    {
        moveCursor(6,9);
        printf("%d free tranasactions remaining for this month",freeTrans);
    }

    moveCursor(6,8);
    printf("Transaction Fee: $%.2f",fee);

    moveCursor(15,13);
    printf("Deposit Amount: $");

    moveCursor(33,13);
    /*get text input from the user and copy it to accountObj->customerObj.lastName*/
    strcpy(amountStr,stringInput(T_STRICT_NUMERIC,1,12));

    amountDec = atoi(amountStr);

    if(amountDec < 1000)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: Deposit amount cannot be less than $1000.00");
        setTextColour(NORMAL_TEXT);
    }
    else if(amountDec%100!=0)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: Despoit amount must be divisible by $100.00");
        setTextColour(NORMAL_TEXT);
    }
    else
    {
        moveCursor(17,27);
        printf("Do you really want to deposit $%d.00?",amountDec);

        moveCursor(30,31);
        printf("[1] Yes        [2] No");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    initScreen();

                    accountObjPtr->balance += amountDec - fee;

                    if(updateAccountInFile(accountObjPtr)==1)
                    {
                        //record transaction info
                        transactionObj.accNumber=accountObjPtr->accNumber;
                        transactionObj.ammount=amountDec;
                        transactionObj.charge = fee;
                        transactionObj.type = DEPOSIT;
                        transactionObj.balance = accountObjPtr->balance;
                        transactionObj.date = time(NULL);
                        strcpy(transactionObj.comments ,"misc");

                        moveCursor(8,20);
                        setTextColour(GREEN_TEXT);
                        printf("Success: $%d.00 was deposited. Your account balance is $%.2f",amountDec,accountObjPtr->balance);
                        setTextColour(NORMAL_TEXT);

                        if(saveTransactionToFile(&transactionObj)==1)
                        {
                            //printf("saved to tranaction log");
                        }
                    }
                    else
                    {
                        accountObjPtr->balance -= amountDec - fee;

                        setTextColour(RED_TEXT);
                        moveCursor(18,20);
                        printf("Failure: An error occurred. Deposit aborted");
                        setTextColour(NORMAL_TEXT);
                    }

                    moveCursor(25,27);
                    printf("PRESS ANY KEY TO CONTINUE");
                    prompt();
                    return CUSTOMER_MAIN_MENU;
                break;
                case '2':
                    return CUSTOMER_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}

int payBillsMenu(account *accountObjPtr)
{
    char amountStr[13];
    float amountDec;
    double fee = 0;
    int freeTrans = 0;
    transaction transactionObj;

    initScreen();

    setCursor(true,1);

    moveCursor(32,4);
    printf("Bill Payment");
    underline(31,5,13);


    //get the number of free transactions remaining for the month
    freeTrans = isAmountTransaction(accountObjPtr->accNumber,5);

    if(freeTrans==0)
    {
        fee = BILL_PAYMENT_CHARGE;
    }
    else
    {
        moveCursor(6,9);
        printf("%d free tranasactions remaining for this month",freeTrans);
    }

    moveCursor(6,8);
    printf("Transaction Fee: $%.2f",fee);

    moveCursor(15,13);
    printf("Bill Payment Amount: $");

    moveCursor(37,13);
    /*get text input from the user and copy it to accountObj->customerObj.lastName*/
    strcpy(amountStr,stringInput(T_CURRENCY,1,12));

    //convert the amount from string to float
    amountDec = atof(amountStr);

    if(accountObjPtr->balance - amountDec + fee < ACCOUNT_MINIMUM_BALANCE)
    {
        moveCursor(10,20);
        setTextColour(RED_TEXT);
        printf("Denied: This bill payment will put your balance below $%.2f",ACCOUNT_MINIMUM_BALANCE);
        setTextColour(NORMAL_TEXT);
    }
    else
    {
        moveCursor(11,27);
        setTextColour(NORMAL_TEXT);
        printf("Do you really want to pay this bill of $%.2f?",amountDec);
        setTextColour(NORMAL_TEXT);

        moveCursor(30,31);
        printf("[1] YES        [2] NO");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    initScreen();
                    accountObjPtr->balance -= amountDec + fee;

                    //if the account was successfully updated in file
                    if(updateAccountInFile(accountObjPtr)==1)
                    {
                        //record transaction info
                        transactionObj.accNumber=accountObjPtr->accNumber;
                        transactionObj.ammount=amountDec;
                        transactionObj.charge = fee;
                        transactionObj.type = BILL_PAYMENT;
                        transactionObj.balance = accountObjPtr->balance;
                        transactionObj.date = time(NULL);
                        strcpy(transactionObj.comments ,"misc");

                        moveCursor(11,20);
                        setTextColour(GREEN_TEXT);
                        printf("Success: Bill amount paid. Your account balance is $%.2f",accountObjPtr->balance);
                        setTextColour(NORMAL_TEXT);

                        //if the transaction is saved to the file
                        if(saveTransactionToFile(&transactionObj)==1)
                        {
                            //printf("saved to tranaction log");
                        }
                    }
                    else //if the account was not updated in file
                    {
                        accountObjPtr->balance += amountDec + fee;

                        moveCursor(12,20);
                        setTextColour(RED_TEXT);
                        printf("Failure: An error occurred. Bill amount was not paid");
                        setTextColour(NORMAL_TEXT);
                    }

                    moveCursor(25,27);
                    printf("PRESS ANY KEY TO CONTINUE");
                    prompt();
                    return CUSTOMER_MAIN_MENU;
                break;
                case '2':
                    return CUSTOMER_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    moveCursor(25,27);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
}

int bankStatement(account *accountObjPtr)
{
    FILE *filePtr;
    transaction transactionObj;
    time_t transactionDate;
    struct tm *transactionTmTime;
    time_t currentDate;
    struct tm *currentTmTime;
    struct tm currentTmTimeObj;
    int rowCount=0;
    int rowStartPosX=0;
    int rowStartPosY=0;
    const char columnSeperator = 179;

    initScreen();
    setCursor(true,1);

    currentDate = time(NULL);
    currentTmTime = localtime(&currentDate);
    currentTmTimeObj = *currentTmTime;

    moveCursor(28,5);
    printf("Monthly Bank Statment");
    underline(26,6,23);

    moveCursor(5,10);
    printf("%s, %d",months[currentTmTimeObj.tm_mon],currentTmTimeObj.tm_year + 1900);

    moveCursor(5,12);
    printf("Account Number: %d",accountObjPtr->accNumber);

    moveCursor(5,14);
    printf("Customer Name: %s %s",accountObjPtr->customerObj.firstName, accountObjPtr->customerObj.lastName);


    filePtr = fopen(TRANSACTION_FILE_PATH,"rb");

    if(filePtr==NULL)
    {
        moveCursor(20,17);
        setTextColour(BRIGHT_WHITE_TEXT);
        printf("Result: There are no transaction records.");
        setTextColour(NORMAL_TEXT);
        moveCursor(28,25);
    }
    else
    {
        rewind(filePtr);
        rowStartPosX = 14;
        rowStartPosY = 18;
        moveCursor(rowStartPosX+4,rowStartPosY+rowCount-1);
        printf("Date/Time");
        moveCursor(rowStartPosX,rowStartPosY+rowCount);
        printf("%c(dd/mm/yyyy hh:mm:ss) %c     Type      %c   balance ($)  %c",columnSeperator,columnSeperator,columnSeperator,columnSeperator,columnSeperator);
        while(!feof(filePtr))
        {
            if(fread(&transactionObj,sizeof(transaction),1,filePtr)==1)
            {
                transactionDate = transactionObj.date;
                transactionTmTime = localtime(&transactionDate);
                //printf("[month:%d year:%d]",transactionTmTime->tm_mon,transactionTmTime->tm_year);
                if(transactionObj.accNumber == accountObjPtr->accNumber && transactionTmTime->tm_mon == currentTmTimeObj.tm_mon && transactionTmTime->tm_year  == currentTmTimeObj.tm_year)
                {
                    rowCount++;
                    moveCursor(rowStartPosX-4,rowStartPosY+rowCount);
                    printf("%3d.",rowCount);
                    moveCursor(rowStartPosX,rowStartPosY+rowCount);
                    printf("%c%02d/%02d/%04d %02d:%02d:%02d   %c%15s%c%16.2f%c",columnSeperator,transactionTmTime->tm_mday,transactionTmTime->tm_mon+1,
                           transactionTmTime->tm_year+1900,transactionTmTime->tm_hour,transactionTmTime->tm_min,transactionTmTime->tm_sec,columnSeperator,transactionTypes[transactionObj.type],columnSeperator,
                           transactionObj.balance,columnSeperator);
                }
            }
        }
        if(rowCount==0)
        {
            moveCursor(15,22);
            setTextColour(BRIGHT_WHITE_TEXT);
            printf("Result: There are no transaction records for this month.");
            setTextColour(NORMAL_TEXT);
            moveCursor(28,25);
        }
        else
        {
            moveCursor(28,rowStartPosY+rowCount+4);
        }
    }
    fclose(filePtr);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return CUSTOMER_MAIN_MENU;
    return 1;
}

int openNewAccount(void)
{
    account accountObj;

    char balance[17]; // used to temporarily store 'balance' input from user

    initScreen();
    setCursor(true,1);

    moveCursor(32,4);
    printf("Open New Account");
    underline(31,5,17);

    moveCursor(15,13);
    printf("First Name:");

    moveCursor(15,15);
    printf("Last Name:");

    moveCursor(15,17);
    printf("DOB:");

    moveCursor(15,19);
    printf("Opening Amount: $");

    moveCursor(15,21);
    printf("PIN:");

    moveCursor(27,13);
    /*get text input from the user and copy it to accountObj->customerObj.fisrtName*/
    strcpy(accountObj.customerObj.firstName,stringInput(T_FREE_TEXT,1,32));

    moveCursor(26,15);
    /*get text input from the user and copy it to accountObj->customerObj.lastName*/
    strcpy(accountObj.customerObj.lastName,stringInput(T_FREE_TEXT,1,40));

    moveCursor(20,17);
    /*get text input from the user and copy it to accountObj->customerObj.dob*/
    strcpy(accountObj.customerObj.dob,stringInput(T_DATE,1,40));

    moveCursor(32,19);
    /*get text input from the user and copy it to balance*/
    strcpy(balance,stringInput(T_CURRENCY,1,16));

    moveCursor(20,21);
    /*get text input from the user and copy it to*/
    strcpy(accountObj.pin,stringInput(T_STRICT_NUMERIC,5,5));

    /*convert 'balance' from a string to a double and store it in accountObj->balance*/
    accountObj.balance = atof(balance);

    accountObj.status = 1;
    accountObj.openedDate = time(NULL);
    accountObj.closedDate = 0;

    moveCursor(25,27);
    printf("[1] SAVE                [2]CANCEL");

    do
    {
        //get single key input from user
        switch( getChar())
        {
            case '1':
                /*if account is saved*/
                if(saveNewAccount(&accountObj)==1)
                {
                    initScreen();
                    setCursor(false,1);

                    moveCursor(20,10);
                    setTextColour(GREEN_TEXT);
                    printf("Account was created successfully.");
                    setTextColour(NORMAL_TEXT);

                    singleFrame(15,45,13,10,"system");
                    moveCursor(22,16);
                    printf("Account Number: %d",accountObj.accNumber);
                    moveCursor(22,17);
                    printf("First Name: %s",accountObj.customerObj.firstName);
                    moveCursor(22,18);
                    printf("Last Name: %s",accountObj.customerObj.lastName);
                    moveCursor(22,19);
                    printf("DOB: %s",accountObj.customerObj.dob);
                    moveCursor(22,20);
                    printf("Balance Amount: $%.2f",accountObj.balance);
                    moveCursor(22,21);
                    printf("Opened Date: %s",ctime(&accountObj.openedDate));
                }
                else /*if account was not saved*/
                {
                    moveCursor(18,33);
                    setTextColour(RED_TEXT);
                    printf("Account was not created. An error occurred.");
                    setTextColour(NORMAL_TEXT);
                }

                moveCursor(25,36);
                printf("PRESS ANY KEY TO CONTINUE");
                prompt();
                return EMPLOYEE_MAIN_MENU;
                //printf("First Name: %s\nLast Name: %s\nDOB: %s\nOpening Amount: %f\nPIN: %s",accountObj.customerObj.fisrtName,accountObj.customerObj.lastName,accountObj.customerObj.dob,accountObj.balance,accountObj.customerObj.pin);
            break;

            case '2':
                return EMPLOYEE_MAIN_MENU;
            break;

        }

    }while(true);
    return 0;
}


int updateAccount(void)
{
    account accountObj;
    char option;

    char balance[17]; // used to temporarily store 'balance' input from user

    char cacheAccNumber[12];

    initScreen();
    setCursor(true,1);

    moveCursor(32,4);
    printf("Update Account");
    underline(31,5,15);

    moveCursor(20,10);
    printf("Enter Account Number:");

    moveCursor(42,10);
    //get account number from user and store it in cacheAccNumber
    strcpy(cacheAccNumber,stringInput(T_STRICT_NUMERIC,1,12));

    accountObj.accNumber = atoi(cacheAccNumber);

    if(getAnyAccountFromFile(&accountObj)==1)
    {
        initScreen();
        setCursor(false,1);
        singleFrame(15,45,7,11,"system");
        moveCursor(22,10);
        printf("Account Number: %d",accountObj.accNumber);
        moveCursor(22,11);
        printf("First Name: %s",accountObj.customerObj.firstName);
        moveCursor(22,12);
        printf("Last Name: %s",accountObj.customerObj.lastName);
        moveCursor(22,13);
        printf("DOB: %s",accountObj.customerObj.dob);
        moveCursor(22,14);
        printf("Balance Amount: $%.2f",accountObj.balance);
        moveCursor(22,15);
        printf("Account Status: %s",accountStatus[accountObj.status]);
        moveCursor(22,16);

        if(accountObj.status==0)
        {
            printf("Opened Date: %s",ctime(&accountObj.openedDate));
            moveCursor(22,17);
            printf("Closed Date: %s",ctime(&accountObj.closedDate));
        }
        else
        {
            printf("Opened Date: %s",ctime(&accountObj.openedDate));
        }

        moveCursor(17,23);
        printf("Choose the field you want to edit:");

        moveCursor(10,26);
        printf("[1] First Name   [2] Last Name   [3] DOB   [4] Status");

        switch(getChar())
        {
            case '1':
                initScreen();
                setCursor(true,1);
                moveCursor(15,20);
                printf("First Name:");
                moveCursor(27,20);
                /*get text input from the user and copy it to accountObj->customerObj.fisrtName*/
                strcpy(accountObj.customerObj.firstName,stringInput(T_FREE_TEXT,1,32));
            break;

            case '2':
                initScreen();
                setCursor(true,1);
                moveCursor(15,20);
                printf("Last Name:");
                moveCursor(27,20);
                /*get text input from the user and copy it to accountObj->customerObj.fisrtName*/
                strcpy(accountObj.customerObj.lastName,stringInput(T_FREE_TEXT,1,32));
            break;

            case '3':
                initScreen();
                setCursor(true,1);
                moveCursor(15,20);
                printf("DOB:");
                moveCursor(20,20);
                /*get text input from the user and copy it to accountObj->customerObj.fisrtName*/
                strcpy(accountObj.customerObj.dob,stringInput(T_FREE_TEXT,1,32));
            break;

            case '4':
                initScreen();
                setCursor(true,1);
                moveCursor(20,17);
                printf("Choose an account status:");
                moveCursor(30,20);
                printf("[1] open        [2]close");
                do
                {
                    //get single key input from user
                    option = getChar();
                    switch(option)
                    {
                        case '1':
                            accountObj.status = 1;
                        break;

                        case '2':
                            accountObj.status = 0;
                        break;
                    }
                }while (option!='1' && option!='2');

        }

        moveCursor(25,27);
        printf("[1] UPDATE               [2]CANCEL");

        do
        {
            //get single key input from user
            switch(getChar())
            {
                case '1':
                    /*if account is saved*/
                    if(updateAccountInFile(&accountObj)==1)
                    {
                        initScreen();
                        setCursor(false,1);

                        moveCursor(20,10);
                        setTextColour(GREEN_TEXT);
                        printf("Account was updated successfully.");
                        setTextColour(NORMAL_TEXT);

                        singleFrame(15,45,16,11,"system");
                        moveCursor(22,19);
                        printf("Account Number: %d",accountObj.accNumber);
                        moveCursor(22,20);
                        printf("First Name: %s",accountObj.customerObj.firstName);
                        moveCursor(22,21);
                        printf("Last Name: %s",accountObj.customerObj.lastName);
                        moveCursor(22,22);
                        printf("DOB: %s",accountObj.customerObj.dob);
                        moveCursor(22,23);
                        printf("Balance Amount: $%.2f",accountObj.balance);
                        moveCursor(22,24);
                        printf("Account Status: %s",accountStatus[accountObj.status]);
                        moveCursor(22,25);

                        if(accountObj.status==0)
                        {
                            printf("Opened Date: %s",ctime(&accountObj.openedDate));
                            moveCursor(22,26);
                            printf("Closed Date: %s",ctime(&accountObj.closedDate));
                        }
                        else
                        {
                            printf("Opened Date: %s",ctime(&accountObj.openedDate));
                        }
                        moveCursor(25,30);
                    }
                    else /*if account was not saved*/
                    {
                        initScreen();

                        moveCursor(18,10);
                        setTextColour(RED_TEXT);
                        printf("Account was not created. An error occurred.");
                        setTextColour(NORMAL_TEXT);
                        moveCursor(25,20);
                    }

                    printf("PRESS ANY KEY TO CONTINUE");

                    prompt();
                    return EMPLOYEE_MAIN_MENU;
                break;

                case 2:
                    return EMPLOYEE_MAIN_MENU;
                break;
            }
        }while(true);
    }
    else
    {
        moveCursor(25,16);
        setTextColour(BRIGHT_WHITE_TEXT);
        printf("Account was not found.");
        setTextColour(NORMAL_TEXT);

        moveCursor(20,21);
        printf("Search again?");

        moveCursor(30,25);
        printf("[1] YES        [2] NO");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    return UPDATE_ACCOUNT_MENU;
                break;
                case '2':
                    return EMPLOYEE_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
}

int saveNewAccount(account *accountObj)
{
    FILE *filePtr;
    account cacheAccountObj;

    filePtr = fopen(ACCOUNT_FILE_PATH,"ab+");
    if(filePtr==NULL)
    {
        return 0;
    }
    else
    {
        rewind(filePtr);

        /*if the file pointer is at the end of the file*/
        if(fread(&cacheAccountObj,sizeof(account),1,filePtr) == 0)
        {
            accountObj->accNumber = 1;

            //write new account to file
            fwrite(accountObj,sizeof(account),1,filePtr);
            fclose(filePtr);
        }
        else /*if point pointer is not at the end of file, there are records in the file*/
        {
            /*attempt tp place  the file pointer one record before the end of the file*/
            fseek(filePtr,-1*sizeof(account),SEEK_END);

            //printf("read amount: %d",fread(&cacheAccountObj,sizeof(account),1,filePtr));
            //prompt();

            /*get the last account record from the file*/
            if(fread(&cacheAccountObj,sizeof(account),1,filePtr)==1)
            {

                /*set account 1 greater than that of the last account in the file*/
                accountObj->accNumber = cacheAccountObj.accNumber + 1;
                fseek(filePtr,0,SEEK_END);
            }
            //printf("[acc#: %d]",accountObj->accNumber);

            //if the new account data is written to file
            if(fwrite(accountObj,sizeof(account),1,filePtr)==1)
            {


            }
            else // if the new account data is not written
            {
               fclose(filePtr);
               return 0;
            }
            fclose(filePtr);
        }
        return 1;
    }
}

int closeAccount(void)
{
    char cacheAccNumber[12];
    account accountObj;

    initScreen();
    setCursor(true,1);

    moveCursor(32,4);
    printf("Close Account");
    underline(31,5,14);


    moveCursor(20,10);
    printf("Enter Account Number:");

    moveCursor(42,10);
    //get account number from user and store it in cacheAccNumber
    strcpy(cacheAccNumber,stringInput(T_STRICT_NUMERIC,1,12));

    accountObj.accNumber = atoi(cacheAccNumber);

    if(getAccountFromFile(&accountObj)==1)
    {
        moveCursor(22,16);
        printf("Account Number: %d",accountObj.pin);
        moveCursor(22,17);
        printf("First Name: %s",accountObj.customerObj.firstName);
        moveCursor(22,18);
        printf("Last Name: %s",accountObj.customerObj.lastName);
        moveCursor(22,19);
        printf("DOB: %s",accountObj.customerObj.dob);
        moveCursor(22,20);
        printf("Balance Amount: $%.2f",accountObj.balance);
        moveCursor(22,21);
        printf("Opened Date: %s",ctime(&accountObj.openedDate));

        moveCursor(17,26);
        printf("Do you really want to close this account?");

        moveCursor(30,31);
        printf("[1] YES        [2] NO");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    initScreen();
                    accountObj.status = 0;
                    accountObj.closedDate = time(NULL);
                    if(updateAccountInFile(&accountObj)==1)
                    {
                        moveCursor(20,10);
                        setTextColour(GREEN_TEXT);
                        printf("Account closed successfully.");
                        setTextColour(NORMAL_TEXT);
                    }
                    else
                    {
                        moveCursor(15,10);
                        setTextColour(RED_TEXT);
                        printf("An error occured while closing the account.");
                        setTextColour(NORMAL_TEXT);
                    }
                    moveCursor(25,20);
                    printf("PRESS ANY KEY TO CONTINUE");
                    prompt();
                    return CLOSE_ACCOUNT_MENU;
                break;
                case '2':
                    return EMPLOYEE_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    else
    {
        moveCursor(25,16);
        setTextColour(BRIGHT_WHITE_TEXT);
        printf("Account was not found.");
        setTextColour(NORMAL_TEXT);

        moveCursor(20,21);
        printf("Search again?");

        moveCursor(30,25);
        printf("[1] YES        [2] NO");

        do
        {
            //get a single key input from user
            switch(  getChar())
            {
                case '1':
                    return CLOSE_ACCOUNT_MENU;
                break;
                case '2':
                    return EMPLOYEE_MAIN_MENU;
                break;
                default:
                break;
            }
        }while(true);
    }
    return 1;
}

int reportsMenuController(void)
{
    initScreen();
    setCursor(false,1);

    moveCursor(32,4);
    printf("Reports Menu");
    underline(31,5,13);

    moveCursor(4,16);
    printf("[1] OPENED/CLOSED ACCOUNTS     [2] DORMANT ACCOUNTS      [3] FEES EARNED");
    moveCursor(2,44);
    printf("[9] MAIN MENU                                                     [0] LOGOUT");
    do
    {
        //get a single key input from user
        switch(  getChar())
        {
            case '1':
                return OPENED_ACCOUNTS_MENU;
            break;
            case '2':
                return DORMANT_ACCOUNTS_MENU;
            break;
            case '3':
                return FEES_EARNED_MENU;
            break;
            case '9':
                return EMPLOYEE_MAIN_MENU;
            break;
            case '0':
                return SELECT_USER_MENU;
            break;
            default:
            break;
        }
    }while(true);
    return 1;
}

int openedClosedAccountsReport(void)
{
    FILE *filePtr;
    account accountObj;
    time_t cacheOpenedDate;
    time_t cacheClosedDate;
    time_t currentDate;
    struct tm *closedTmTime;
    struct tm *openedTmTime;
    struct tm *currentTmTime;
    struct tm currentTmTimeObj;
    int closedCount = 0;
    int openedCount = 0;

    initScreen();
    setCursor(false,1);

    moveCursor(25,4);
    printf("Open/Close Account Report");
    underline(24,5,26);


    currentDate = time(NULL);
    currentTmTime = localtime(&currentDate);
    currentTmTimeObj = *currentTmTime;

    filePtr = fopen(ACCOUNT_FILE_PATH,"rb");

    if(filePtr==NULL)
    {

    }
    else
    {
        rewind(filePtr);
        while(!feof(filePtr))
        {
            if(fread(&accountObj,sizeof(account),1,filePtr)==1)
            {
                //cacheOpenedDate = time(&accountObj.openedDate);
                openedTmTime = localtime(&accountObj.openedDate);

                if(openedTmTime->tm_year == currentTmTimeObj.tm_year && openedTmTime->tm_mon == currentTmTimeObj.tm_mon)
                {

                    openedCount+=1;
                }

                //cacheClosedDate = time(&accountObj.closedDate);
                closedTmTime = localtime(&accountObj.closedDate);

                if(accountObj.closedDate !=0 && closedTmTime->tm_year == currentTmTimeObj.tm_year && closedTmTime->tm_mon == currentTmTimeObj.tm_mon)
                {
                    closedCount+=1;
                }
            }
        }
        moveCursor(20,11);
        printf("%s, %d",months[currentTmTimeObj.tm_mon],currentTmTimeObj.tm_year + 1900);
        moveCursor(20,15);
        printf("Opened Accounts: %d",openedCount);
        moveCursor(20,16);
        printf("Closed Accounts: %d",closedCount);
        moveCursor(28,25);
        printf("PRESS ANY KEY TO CONTINUE");
        prompt();
        return REPORTS_MENU;
    }
}


int feesEarnedReport(void)
{
    FILE *filePtr;
    transaction transactionObj;
    time_t transactionDate;
    struct tm *transactionTmTime;
    char cacheMonthStr[3];
    char cacheYearStr[5];
    int cacheMonthInt=0;
    int cacheYearInt=0;
    int rowCount=0;
    int rowStartPosX=0;
    int rowStartPosY=0;
    const char columnSeperator = 179;

    initScreen();
    setCursor(true,1);

    moveCursor(25,4);
    printf("Bank Fees Earned Report");
    underline(24,5,24);


    moveCursor(20,8);
    printf("Month:         e.g. 07");
    moveCursor(20,10);
    printf("Year:         e.g. 2011");

    moveCursor(27,8);
    //get month from user and store it in cacheAccNumber
    strcpy(cacheMonthStr,stringInput(T_STRICT_NUMERIC,2,2));

    moveCursor(26,10);
    //get month from user and store it in cacheAccNumber
    strcpy(cacheYearStr,stringInput(T_STRICT_NUMERIC,4,4));

    cacheMonthInt = atoi(cacheMonthStr);
    cacheYearInt = atoi(cacheYearStr);

    filePtr = fopen(TRANSACTION_FILE_PATH,"rb");

    if(filePtr==NULL)
    {
        moveCursor(20,17);
        setTextColour(BRIGHT_WHITE_TEXT);
        printf("Result: There are no transaction records.");
        setTextColour(NORMAL_TEXT);
        moveCursor(28,25);
    }
    else
    {
        rewind(filePtr);
        rowStartPosX = 5;
        rowStartPosY = 14;
        moveCursor(rowStartPosX+4,rowStartPosY+rowCount-1);
        printf("Date/Time");
        moveCursor(rowStartPosX,rowStartPosY+rowCount);
        printf("%c(dd/mm/yyyy hh:mm:ss) %c          Type        %c    Acc#    %c   Fee ($)  %c",columnSeperator,columnSeperator,columnSeperator,columnSeperator,columnSeperator);
        while(!feof(filePtr))
        {
            if(fread(&transactionObj,sizeof(transaction),1,filePtr)==1)
            {
                transactionDate = transactionObj.date;
                transactionTmTime = localtime(&transactionDate);
                //printf("[month:%d year:%d]",transactionTmTime->tm_mon,transactionTmTime->tm_year);
                if(transactionTmTime->tm_mon == cacheMonthInt-1 && transactionTmTime->tm_year+1900  == cacheYearInt)
                {
                    rowCount++;
                    moveCursor(rowStartPosX-4,rowStartPosY+rowCount);
                    printf("%3d.",rowCount);
                    moveCursor(rowStartPosX,rowStartPosY+rowCount);
                    printf("%c%02d/%02d/%04d %02d:%02d:%02d   %c%22s%c%12d%c%12.2f%c",columnSeperator,transactionTmTime->tm_mday,transactionTmTime->tm_mon+1,
                           transactionTmTime->tm_year+1900,transactionTmTime->tm_hour,transactionTmTime->tm_min,transactionTmTime->tm_sec,columnSeperator,transactionTypes[transactionObj.type],columnSeperator,transactionObj.accNumber,columnSeperator,
                           transactionObj.charge,columnSeperator);
                }
            }
        }
        if(rowCount==0)
        {
            moveCursor(20,17);
            setTextColour(BRIGHT_WHITE_TEXT);
            printf("Result: There are no transaction records.");
            setTextColour(NORMAL_TEXT);
            moveCursor(28,25);
        }
        else
        {
            moveCursor(28,rowStartPosY+rowCount+4);
        }
    }
    fclose(filePtr);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return REPORTS_MENU;
}

int dormantAccount(void)
{
    FILE *filePtr;
    account accountObj;
    int dormantStatus;
    int rowCount = 0;
    int yStart = 14;
    const char columnSeperator = 179;
    char fullName[40];

    initScreen();
    setCursor(false,1);

    moveCursor(28,8);
    printf("Dormant Accounts Report");
    underline(27,9,23);

    filePtr = fopen(ACCOUNT_FILE_PATH,"rb");
    if(filePtr==NULL)
    {

    }
    else
    {
        //fseek(filePtr,sizeof(account),SEEK_END);
        rewind(filePtr);

        moveCursor(14,yStart+rowCount);
        printf("%c Account Number  %c             Account Holder             %c",columnSeperator,columnSeperator,columnSeperator);

        while(!feof(filePtr))
        {
            if(fread(&accountObj,sizeof(account),1,filePtr)==1)
            {
                dormantStatus = isAccountDormant(accountObj);
                if(dormantStatus==1)
                {
                    rowCount++;
                    moveCursor(14-3,yStart+rowCount);
                    printf("%d.",rowCount);

                    strcpy(fullName,accountObj.customerObj.firstName);
                    strcat(fullName," ");
                    strcat(fullName,accountObj.customerObj.lastName);

                    moveCursor(14,yStart+rowCount);
                    printf("%c%17d%c%40s%c",columnSeperator,accountObj.accNumber,columnSeperator,fullName,columnSeperator);
                }
            }
        }
        if(rowCount==0)
        {
            moveCursor(20,17);
            setTextColour(BRIGHT_WHITE_TEXT);
            printf("Result: There are no dormant accounts.");
            setTextColour(NORMAL_TEXT);
            moveCursor(28,25);
        }
        else
        {
            moveCursor(28,yStart+rowCount+4);
        }
    }
    fclose(filePtr);
    printf("PRESS ANY KEY TO CONTINUE");
    prompt();
    return REPORTS_MENU;
}

/*An account is considered dormant if there are no transactions in the past 6 months*/
int isAccountDormant(account accountObj)
{
    FILE *filePtr;
    transaction transactionObj;
    int tranCount = 0;

    time_t transactionDate;
    time_t currentDate;
    time_t openedDate;

    struct tm *transactionTmTime;
    struct tm *currentTmTime;
    struct tm currentTmTimeObj;
    struct tm *openedTmTime;


    filePtr = fopen(TRANSACTION_FILE_PATH,"ab+");

    currentDate = time(NULL);
    currentTmTime = localtime(&currentDate);
    currentTmTimeObj = *currentTmTime;

    if(filePtr==NULL)
    {
        return -1;
    }
    else
    {
        while(!feof(filePtr))
        {
            if(fread(&transactionObj,sizeof(transaction),1,filePtr)==1)
            {
                transactionDate = transactionObj.date;

                transactionTmTime = localtime(&transactionDate);
                if(transactionObj.accNumber == accountObj.accNumber)
                {
                    tranCount++;
                    if(currentTmTime->tm_mon>=5)
                    {
                        if(transactionTmTime->tm_year == currentTmTimeObj.tm_year && transactionTmTime->tm_mon  > currentTmTimeObj.tm_mon - 5)
                        {
                            fclose(filePtr);
                            return 0;
                        }
                    }
                    else
                    {
                        if(transactionTmTime->tm_year == currentTmTimeObj.tm_year - 1 && transactionTmTime->tm_mon  > 11 - (5 - transactionTmTime->tm_mon))
                        {
                            fclose(filePtr);
                            return 0;
                        }
                    }
                    //&& transactionTmTime->tm_mon == currentTmTime->tm_mon
                }
            }
        }
        if(tranCount==0)
        {

            openedDate = accountObj.openedDate;
            openedTmTime = localtime(&openedDate);

            transactionTmTime = localtime(&transactionDate);
            if(currentTmTime->tm_mon>=5)
            {
                if(openedTmTime->tm_year == currentTmTimeObj.tm_year && openedTmTime->tm_mon  > currentTmTimeObj.tm_mon - 5)
                {
                    fclose(filePtr);
                    return 0;
                }
            }
            else
            {
                if(openedTmTime->tm_year == currentTmTimeObj.tm_year - 1 && openedTmTime->tm_mon  > 11 - (5 - openedTmTime->tm_mon))
                {
                    fclose(filePtr);
                    return 0;
                }
            }
            fclose(filePtr);
            return 1;
        }
        else
        {
            fclose(filePtr);
            return 1;
        }
    }
}

int updateAccountInFile(account *accountObjPtr)
{
    FILE *filePtr;
    account accountObj;

    filePtr = fopen(ACCOUNT_FILE_PATH,"rb+");
    if(filePtr==NULL)
    {
    }
    else
    {
        rewind(filePtr);

        while(!feof(filePtr))
        {
            fread(&accountObj,sizeof(account),1,filePtr);
            if(accountObj.accNumber == accountObjPtr->accNumber)
            {
                fseek(filePtr,-1*sizeof(account),SEEK_CUR);
                fwrite(accountObjPtr,sizeof(account),1,filePtr);
                fclose(filePtr);
                return 1;
            }
        }
        fclose(filePtr);
    }
    return 0;
}

int getAccountFromFile(account *accountObjPtr)
{
    FILE *filePtr;
    account accountObj;

    accountObj.accNumber = 0;

    filePtr = fopen(ACCOUNT_FILE_PATH,"rb");
    if(filePtr==NULL)
    {

    }
    else
    {
        //fseek(filePtr,sizeof(account),SEEK_END);
        rewind(filePtr);
        while(!feof(filePtr))
        {
            fread(&accountObj,sizeof(account),1,filePtr);
            if(accountObj.accNumber == accountObjPtr->accNumber && accountObj.status!=0)
            {
                *accountObjPtr = accountObj;
                fclose(filePtr);
                return 1;
            }
        }
        fclose(filePtr);
    }
    return 0;
}

int getAnyAccountFromFile(account *accountObjPtr)
{
    FILE *filePtr;
    account accountObj;

    accountObj.accNumber = 0;

    filePtr = fopen(ACCOUNT_FILE_PATH,"rb");
    if(filePtr==NULL)
    {

    }
    else
    {
        //fseek(filePtr,sizeof(account),SEEK_END);
        rewind(filePtr);
        while(!feof(filePtr))
        {
            if(fread(&accountObj,sizeof(account),1,filePtr)==1)
            {
                if(accountObj.accNumber == accountObjPtr->accNumber)
                {
                    *accountObjPtr = accountObj;
                    fclose(filePtr);
                    return 1;
                }
            }
            else
            {

            }
        }
        fclose(filePtr);
    }
    return 0;
}

int saveTransactionToFile(transaction *transactionObjPtr)
{
    FILE *filePtr;

    filePtr = fopen(TRANSACTION_FILE_PATH,"ab");
    if(filePtr==NULL)
    {
    }
    else
    {
        if(fwrite(transactionObjPtr,sizeof(transaction),1,filePtr)==1)
        {
            fclose(filePtr);
            return 1;
        }
        else
        {
            fclose(filePtr);
            return -1;
        }
    }
    return 0;
}

int isAmountTransaction(int accNum, int amount)
{
    FILE *filePtr;
    transaction transactionObj;
    int tranCount = 0;

    time_t transactionDate;
    time_t currentDate;

    struct tm *transactionTmTime;
    struct tm * currentTmTime;
    struct tm currentTmTimeObj;


    filePtr = fopen(TRANSACTION_FILE_PATH,"ab+");

    currentDate = time(NULL);
    currentTmTime = localtime(&currentDate);
    currentTmTimeObj = *currentTmTime;

    if(filePtr==NULL)
    {

    }
    else
    {
        while(!feof(filePtr))
        {
            if(fread(&transactionObj,sizeof(transaction),1,filePtr)==1)
            {
                transactionDate = transactionObj.date;

                transactionTmTime = localtime(&transactionDate);
                if(transactionObj.accNumber == accNum && transactionTmTime->tm_mon == currentTmTimeObj.tm_mon && transactionTmTime->tm_year  == currentTmTimeObj.tm_year)
                {
                    tranCount+=1;
                    if(tranCount==amount)
                    {
                        fclose(filePtr);
                        return amount-tranCount;
                    }
                }
            }
        }
        return amount-tranCount;
    }
    fclose(filePtr);
    return 0;
}

int confirmationPrompt(int xpos, int ypos)
{
    setCursor(false,0);
    moveCursor(xpos,ypos);
    printf("[1] YES        [2] NO");

    do
    {
        //get a single key input from user
        switch(  getChar())
        {
            case '1':
                return 1;
            break;
            case '2':
                return 2;
            break;
            default:
            break;
        }
    }while(true);

}

float bonusCredit(char provider, float creditAmount)
{
    switch(provider)
    {
        case '2':
        case '3':
        case '4':
            return DIGICEL_BONUS * creditAmount * 0.01;
        break;

        case '5':
        case '6':
            return CLARO_BONUS * creditAmount * 0.01;

        case '7':
        case '8':
        case '9':
            return LIME_BONUS * creditAmount * 0.01;
    }
}

char * getServiceProvider (char provider)
{
    switch(provider)
    {
        case '2':
        case '3':
        case '4':
            return "Digicel";
        break;

        case '5':
        case '6':
            return "Claro";

        case '7':
        case '8':
        case '9':
            return "LIME";
    }
}

void singleFrame(int x,int xLength,int y , int yLength, char type[30])
{
    char TopLeftChar = 218;
    char BottomLeftChar = 192;
    char TopRightChar = 191;
    char BottomRightChar = 217;
    char HorizontalSingleLine = 196;
    char VerticalSingleLine = 179;
    char LeftSystemWindowConnector = 195;
    char RightSystemWindowConnector = 180;
    int i;
    for(i=x;i<=x+xLength;i++)
    {
        moveCursor(i,y);
        printf("%c",HorizontalSingleLine);
    }
    for(i=y;i<=y+yLength;i++)
    {
        moveCursor(x+xLength,i);
        printf("%c",VerticalSingleLine);
    }
    for(i=x+xLength;i>=x;i--)
    {
        moveCursor(i,y+yLength);
        printf("%c",HorizontalSingleLine);
    }
    for(i=y+yLength;i>=y;i--)
    {
        moveCursor(x,i);
        printf("%c",VerticalSingleLine);
    }
    moveCursor(x,y);
    printf("%c",TopLeftChar);
    moveCursor(x+xLength,y);
    printf("%c",TopRightChar);
    moveCursor(x+xLength,y+yLength);
    printf("%c",BottomRightChar);
    moveCursor(x,y+yLength);
    printf("%c",BottomLeftChar);
    if(strcmp(type,"system")==0)
    {
        for(i=x;i<=x+xLength;i++)
        {
            moveCursor(i,y+2);
            printf("%c",HorizontalSingleLine);
        }
        moveCursor(x,y+2);
        printf("%c",LeftSystemWindowConnector);
        moveCursor(x+xLength,y+2);
        printf("%c",RightSystemWindowConnector);
    }
    moveCursor(0,0);
}

void underline(int xpos,int ypos, int xLength)
{
    char HorizontalSingleLine = 196;

    int i;

    for(i=xpos;i<=xpos+xLength;i++)
    {
        moveCursor(i,ypos);
        printf("%c",HorizontalSingleLine);
    }
}

char* stringInput(int inputType, int minLenght, int maxLenght)
{
    char asciiKeyCache;
    int virtualKeyCache;
    char *stringBuffer;
    int position = 0;

    //dynamically assign storage space
    stringBuffer = (char*) malloc(maxLenght+1);

    if(stringBuffer==NULL)
    {
        return stringBuffer;
    }
    //structure containing information of the console input events
    MY_INPUT_RECORD eventBuffer;


    while(true)
    {
        //get all console input events (mouse and key)
        eventBuffer = getAllInput();

        //access the latter ascii key character inputted
        asciiKeyCache =  eventBuffer.Event.KeyEvent.uChar.AsciiChar;

        if(position <= maxLenght - 1)
        {
            switch(inputType)
            {
                case T_PASSWORD:
                    if(isalnum(asciiKeyCache) || ispunct(asciiKeyCache))
                    {
                        printf("*");
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_CURRENCY:
                    if(isdigit(asciiKeyCache) || asciiKeyCache == '.')
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_REAL_NUMERIC:
                    if(isdigit(asciiKeyCache) || asciiKeyCache == '.' || asciiKeyCache=='-' )
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_INTEGER_NUMBERIC:
                    if(isdigit(asciiKeyCache) || asciiKeyCache=='-')
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_STRICT_NUMERIC:
                    if(isdigit(asciiKeyCache))
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_FREE_TEXT:
                    if(isalnum(asciiKeyCache) || ispunct(asciiKeyCache))
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }

                break;

                case T_DATE:
                    if(isdigit(asciiKeyCache) || asciiKeyCache=='/' )
                    {
                        printf("%c",asciiKeyCache);
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                break;

                case T_TELEPHONE:
                    if(isdigit(asciiKeyCache))
                    {
                        if(position==3)
                        {
                            stringBuffer[position]='-';
                            printf("-");
                        }
                        else
                        {

                            printf("%c",asciiKeyCache);
                            stringBuffer[position] = asciiKeyCache;
                        }
                        position++;
                    }
                break;
                default:
                break;
            }
        }

        //access the the latter control key that was pressed
        virtualKeyCache = eventBuffer.Event.KeyEvent.wVirtualKeyCode;

        switch(virtualKeyCache)
        {
            case ENTER_KEY:
                stringBuffer[position] = '\0';
                return stringBuffer;
            break;
            case ESC_KEY:
            break;
            case DOWN_KEY:
            case UP_KEY:
            case TAB_KEY:
            case F1_KEY:
            case F3_KEY:
            break;

            case RIGHT_KEY:
            break;

            case LEFT_KEY:
            break;

            case BACKSPACE_KEY:
                if(position>0)
                {
                    printf("\b \b");
                    stringBuffer[position] = '\0';
                    position--;
                }
            break;

            case SPACEBAR_KEY:
                if(position <= maxLenght - 1)
                {
                    if(inputType && T_STRICT_NUMERIC && inputType != T_CURRENCY && inputType !=T_TELEPHONE)
                    {
                        if(inputType == T_PASSWORD )
                        {
                            printf("*");
                        }
                        else
                        {
                            printf("%c",asciiKeyCache);
                        }
                        stringBuffer[position] = asciiKeyCache;
                        position++;
                    }
                }
            break;
        }
    }
}

void prompt(void)
{
    //structure containing information of the console input events
    MY_INPUT_RECORD eventBuffer;

    do
    {
        //get all console input events (mouse and key)
        eventBuffer = getAllInput();
    }while(eventBuffer.EventType != KEY_EVENT && !eventBuffer.Event.KeyEvent.bKeyDown);
}

char getChar(void)
{
    char cacheChar;
    //structure containing information of the console input events
    MY_INPUT_RECORD eventBuffer;
    do
    {
        //get all console input events (mouse and key)
        eventBuffer = getAllInput();

        //access the latter ascii key character inputted
        cacheChar = eventBuffer.Event.KeyEvent.uChar.AsciiChar;
    }while(!isalnum(cacheChar));

    return cacheChar;
}

